﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using __Able.Network.Packet;
using __Able.Network.Utils;

namespace PDM.Packet
{
    /// <summary>
    /// -------------------------------------------------
    ///         [包头]         |  [包体]   |  [包尾]
    /// -------------------------------------------------
    ///  [版本号] | [指令标记] |           |   
    /// -------------------------------------------------
    ///  byte[4]  |   ushort   |  byte[]   |  byte
    /// -------------------------------------------------
    ///     4     |     2      |     n     |   1
    /// -------------------------------------------------
    /// </summary>
    public abstract class PDMPacket : BasicPacket
    {
        /// <summary>
        /// 版本
        /// </summary>
        /// <value></value>
        public byte[] Version { get; protected set; }
        /// <summary>
        /// 指令标记
        /// </summary>
        /// <value></value>
        public ushort Token { get; protected set; }
        /// <summary>
        /// 包buf
        /// </summary>
        public byte[] ToByteArray()
        {
            return _buf.ToByteArray();
        }
        /// <summary>
        /// 包尾
        /// </summary>
        public byte Tail
        {
            get
            {
                return 0xff;
            }
        }
        /// <summary>
        /// 包创建时间
        /// </summary>
        /// <value></value>
        public DateTime DateTime { get; protected set; }

        /// <summary>
        /// 包的描述性名称
        /// </summary>
        public override string PacketName
        {
            get
            {
                return string.Format("{0}-{1}-{2}-{3}-{4}", Version[0], Version[1], Version[2], Version[3], Token);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="version"></param>
        /// <param name="token"></param>
        /// <param name="body"></param>
        public PDMPacket(byte[] version, ushort token)
        {
            this.Token = token;
            this.Version = version;
            this.DateTime = DateTime.Now;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="buf"></param>
        public PDMPacket(byte[] version, ushort token, ByteBuffer buf)
        {
            this.Version = buf.GetByteArray(4);
            this.Token = buf.GetUShort();
            ParseBody(buf);
            if (this.Tail != buf.Get())
                throw new Exception("包尾有误: " + this.PacketName);
        }

        /// <summary>
        /// 
        /// </summary>
        protected virtual void Fill()
        {
            _buf.Initialize();

            // 写入包头
            _buf.Put(this.Version);
            _buf.PutUShort(this.Token);

            // 写入包体
            PutBody(_buf);

            // 写入包尾
            _buf.Put(this.Tail);
        }
        /// <summary>
        /// 初始化包体
        /// </summary>
        /// <param name="buf">The buf.</param>
        protected abstract void PutBody(ByteBuffer buf);
        /// <summary>
        /// 从buf中解析包体
        /// </summary>
        /// <param name="buf">The buf.</param>
        protected abstract void ParseBody(ByteBuffer buf);
    }
}
